home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / gsdb21.arc / GS_EDIT.PAS < prev    next >
Pascal/Delphi Source File  |  1991-01-04  |  22KB  |  749 lines

  1. Unit GS_Edit;
  2. interface
  3. uses
  4.    CRT,
  5.    Dos,
  6.    GS_KeyI,
  7.    GS_Scrn,
  8.    GS_Wind,
  9.    GS_Error,
  10.    GS_Strng;
  11. type
  12.    GS_Edit_Pntr = ^GS_Edit_Line;
  13.    GS_Edit_Line = record
  14.                      Next_Line,
  15.                      Prev_Line  : GS_Edit_Pntr;
  16.                      Return_Cod : byte;
  17.                      Line_Size  : integer;
  18.                      Valu_Line  : string;
  19.                   end;
  20.  
  21.    GS_Edit_Blok = record
  22.                      Blok_Line,
  23.                      Blok_Colm  : integer;
  24.                   end;
  25.  
  26.    GS_Edit_Objt = object
  27.                      First_Line,
  28.                      End_Line,
  29.                      Work_Line   : GS_Edit_Pntr;
  30.                                       {Used to track lines}
  31.                      Cursor_LocX,
  32.                      Cursor_LocY : word;
  33.                                       {Hold cursor location}
  34.                      Active_Line,     {Current line number}
  35.                      Total_Lines,     {Total number of lines}
  36.                      Screen_Top,      {Line number at top of screen}
  37.                      Screen_Btm  : longint;
  38.                                       {Line Number at bottom of screen}
  39.                      CursorPos   : integer;
  40.                                       {Position in line}
  41.                      CursorLine  : integer;
  42.                                       {Line currently working on}
  43.                      Temp_Line   : string;
  44.                                       {work area during wordwrap}
  45.                      Edit_Lgth   : integer;
  46.                                       {Max size of eaach line}
  47.                      Lines_Avail : integer;
  48.                                       {Number of lines that will fit in the}
  49.                                       {window on the screen}
  50.                      Ch_Work     : char;
  51.                                       {Hold area for keystrokes}
  52.                      Word_Wrap   : boolean;
  53.                                       {True sets word wrap on}
  54.                      WW_Flag     : boolean;
  55.                                       {Internal flag for wordwrap condition}
  56.                      Blok_Begin,
  57.                      Blok_Fini   : GS_Edit_Blok;
  58.                                       {Future use for block operations}
  59.  
  60.  
  61.                      function    Byte_Count : longint;
  62.                      procedure   Check_Func_Keys;
  63.                      procedure   Clear_Editor;
  64.                      procedure   Edit;
  65.                      Procedure   Edit_Line;
  66.                      function    Find_Line(linenum : integer) : boolean;
  67.                      function    Get_Line_Mem(lth : integer) : pointer;
  68.                      constructor Init;
  69.                      Procedure   Rel_Line_Mem(linenum : integer);
  70.                      Procedure   Show_Lines(b, e :integer);
  71.                      Procedure   View;
  72.                      Procedure   WordWrap(Fline : string);
  73.                      Procedure   Pressed_Bsp;
  74.                      Procedure   Pressed_CrtlY;
  75.                      Procedure   Pressed_Del;
  76.                      Procedure   Pressed_DnAr;
  77.                      Procedure   Pressed_F1;
  78.                      Procedure   Pressed_Ret;
  79.                      Procedure   Pressed_UpAr;
  80.                      Procedure   Pressed_PgUp;
  81.                      Procedure   Pressed_PgDn;
  82.                   end;
  83.  
  84.  
  85. implementation
  86. var
  87.    StatWin,
  88.    HelpWin,
  89.    EditWin  : GS_Wind_Objt;
  90.  
  91. function GS_Edit_Objt.Byte_Count : longint;
  92. var
  93.    i : longint;
  94.    p : GS_Edit_Pntr;
  95. begin
  96.    i := 0;
  97.    p := First_Line;
  98.    while (p <> nil) do
  99.    begin
  100.       i := i + length(p^.Valu_Line) + 2;
  101.                                       {Add length of line + CR/LF chars}
  102.       p := p^.Next_Line;
  103.    end;
  104.    inc(i);                            {Add one for EOF byte}
  105.    Byte_Count := i;
  106. end;
  107.  
  108. procedure GS_Edit_Objt.Clear_Editor;
  109. begin
  110.    Work_Line := First_Line;
  111.    while (Work_Line <> nil) do
  112.    begin
  113.       End_Line := Work_Line^.Next_Line;
  114.       FreeMem(Work_Line,Work_Line^.Line_Size);
  115.       Work_Line := End_Line;
  116.    end;
  117.    First_Line := nil;
  118.    End_Line := nil;
  119.    Work_Line := nil;
  120.    Active_line := 0;
  121.    Total_Lines := 0;
  122. end;
  123.  
  124.  
  125. constructor GS_Edit_Objt.Init;
  126. begin
  127.    First_Line := nil;
  128.    End_Line := nil;
  129.    Work_Line := nil;
  130.    Word_Wrap := true;
  131.    WW_Flag := false;
  132.    Active_Line := 0;
  133.    Total_Lines := 0;
  134.    Screen_Top := 0;
  135.    Screen_Btm := 0;
  136.    Ch_Work := #0;
  137.    CursorPos := 1;
  138.    CursorLine := 1;
  139.    Temp_Line := '';
  140.    GS_KeyI_Ins := True;               {Start in insert mode}
  141.    Edit_Lgth := 32;
  142.    StatWin.InitWin(1,23,80,25,Yellow,Black,LightGray,Black,LightGray,
  143.                    true,'',true);
  144.    EditWin.InitWin(1,1,80,22,LightGray,Black,LightGray,Black,LightGray,
  145.                    false,'',true);
  146.    HelpWin.InitWin(29,2,51,20,Yellow,Black,Yellow,Black,LightGray,
  147.                    true,'[ Edit Help ]',true);
  148. end;
  149.  
  150.  
  151. procedure GS_Edit_Objt.Pressed_F1;
  152. var
  153.    cc : char;
  154. begin
  155.    HelpWin.SetWin;
  156.    writeln('Toggle Ins  - Ins');
  157.    writeln('Delete Char - Del');
  158.    writeln('Delete Line - Ctl-Y');
  159.    writeln('Press any Key');
  160.    cc := ReadKey;
  161.    if cc = #0 then cc := ReadKey;
  162.    HelpWin.RelWin;
  163. end;
  164.  
  165.  
  166. procedure GS_Edit_Objt.Pressed_Bsp;
  167. var
  168.    bb : byte;
  169.    ss : string;
  170.    ll : boolean;
  171. begin
  172.    if CursorPos > 1 then
  173.    begin
  174.       Delete(Work_Line^.Valu_Line, Pred(CursorPos), 1);
  175.       GoToXY(1, CursorLine);
  176.       Write(Work_Line^.Valu_Line);
  177.       ClrEol;
  178.       Dec(CursorPos);
  179.    end
  180.    else
  181.    begin
  182.       if Active_Line > 1 then
  183.       begin
  184.          bb := Work_line^.Return_Cod;
  185.          ss := Work_Line^.Valu_Line;
  186.          if Active_Line < Total_Lines then
  187.          begin
  188.             Pressed_CrtlY;
  189.             Pressed_UpAr;
  190.          end else Pressed_CrtlY;
  191.          Work_Line^.Return_Cod := bb;
  192.          ss := Work_Line^.Valu_Line + ss;
  193.          CursorPos := length(Work_Line^.Valu_Line);
  194.          WordWrap(ss);
  195.          GotoXY(1,succ(Active_Line-Screen_Top));
  196.          write(Work_Line^.Valu_Line);
  197.       end;
  198.    end;
  199. end;
  200.  
  201. procedure GS_Edit_Objt.Pressed_Del;
  202. begin
  203.    if CursorPos <= Length(Work_Line^.Valu_Line) then
  204.    begin
  205.       Delete(Work_Line^.Valu_Line, CursorPos, 1);
  206.       GoToXY(1, CursorLine);
  207.       Write(Work_Line^.Valu_Line);
  208.       ClrEol;
  209.    end;
  210. end;
  211.  
  212. procedure GS_Edit_Objt.Pressed_PgDn;
  213. begin         {Page Down}
  214.    Active_Line := pred(Screen_Top + Lines_Avail);
  215.    if Active_Line > Total_Lines then Active_Line := Total_Lines;
  216.    if not Find_Line(Active_Line) then
  217.    begin
  218.       ShowError(710,'Pressed_PgDn');
  219.       exit;
  220.    end;
  221.    if Active_Line <> Screen_Top then Show_Lines(Active_Line,Total_Lines);
  222.    CursorLine := 1;
  223.    if length(Work_Line^.Valu_Line)+1 < CursorPos then
  224.       CursorPos := length(Work_Line^.Valu_Line)+1;
  225. end;
  226.  
  227. procedure GS_Edit_Objt.Pressed_PgUp;
  228. begin         {Page Up}
  229.    if Active_Line <= 1 then exit;
  230.    Active_Line := succ(Screen_Top - Lines_Avail);
  231.    if Active_Line < 1 then Active_Line := 1;
  232.    if not Find_Line(Active_Line) then
  233.    begin
  234.       ShowError(710,'Pressed_PgUp');
  235.       exit;
  236.    end;
  237.    if Active_Line < Screen_Top then Show_Lines(Active_Line,Total_Lines);
  238.    CursorLine := 1;
  239.    if length(Work_Line^.Valu_Line)+1 < CursorPos then
  240.       CursorPos := length(Work_Line^.Valu_Line)+1;
  241. end;
  242.  
  243. procedure GS_Edit_Objt.Pressed_UpAr;
  244. begin         {Up Arrow}
  245.    if Active_Line <= 1 then exit;
  246.    if not Find_Line(pred(Active_Line)) then
  247.    begin
  248.       ShowError(710,'Pressed_UpAr');
  249.       exit;
  250.    end;
  251.    if Active_Line < Screen_Top then
  252.    begin
  253.       gotoxy(1,1);
  254.       InsLine;
  255.       dec(Screen_Top);
  256.       write(Work_Line^.Valu_Line);
  257.    end;
  258.    if length(Work_Line^.Valu_Line)+1 < CursorPos then
  259.       CursorPos := length(Work_Line^.Valu_Line)+1;
  260. end;
  261.  
  262. procedure GS_Edit_Objt.Pressed_DnAr;
  263. begin         {Down Arrow}
  264.    if Active_Line >= Total_Lines then exit;
  265.    if not Find_Line(succ(Active_Line)) then
  266.    begin
  267.       ShowError(710,'Pressed_DnAr');
  268.       exit;
  269.    end;
  270.    if Active_Line-Screen_Top >= Lines_Avail then
  271.    begin
  272.       GoToXY(1,1);
  273.       DelLine;
  274.       inc(Screen_Top);
  275.       GotoXY(1,Lines_Avail);
  276.       write(Work_Line^.Valu_Line);
  277.    end;
  278.    if length(Work_Line^.Valu_Line)+1 < CursorPos then
  279.    CursorPos := length(Work_Line^.Valu_Line)+1;
  280. end;
  281.  
  282.  
  283. procedure GS_Edit_Objt.Pressed_Ret;
  284. begin         {Return}
  285.    GS_KeyI_Ret := true;
  286.    Work_Line^.Return_Cod := $0D;
  287.    if GS_KeyI_Ins then
  288.    begin
  289.       ClrEol;
  290.       Temp_Line := Work_Line^.Valu_Line;
  291.       Work_Line^.Valu_Line := substr(Work_Line^.Valu_Line,1,pred(CursorPos));
  292.       delete(Temp_Line,1,pred(CursorPos));
  293.       Work_Line := Get_Line_Mem(Edit_Lgth);
  294.       Work_Line^.Valu_Line  := Temp_Line;
  295.       if Active_Line-Screen_Top >= Lines_Avail then
  296.       begin
  297.          GoToXY(1,1);
  298.          DelLine;
  299.          inc(Screen_Top);
  300.          GotoXY(1,Lines_Avail);
  301.          write(Work_Line^.Valu_Line);
  302.       end else
  303.       begin
  304.          GotoXY(1,succ(CursorLine));
  305.          InsLine;
  306.          write(Work_Line^.Valu_Line);
  307.       end;
  308.    end
  309.    else
  310.    begin
  311.       if Active_Line-Screen_Top >= Lines_Avail then
  312.       begin
  313.          GoToXY(1,1);
  314.          DelLine;
  315.          inc(Screen_Top);
  316.       end;
  317.       if not Find_Line(succ(Active_Line)) then
  318.       Work_Line := Get_Line_Mem(Edit_Lgth);
  319.       GotoXY(1,CursorLine);
  320.       write(Work_Line^.Valu_Line);
  321.    end;
  322.    CursorPos := 1;
  323. end;
  324.  
  325. procedure GS_Edit_Objt.Pressed_CrtlY;
  326. var
  327.    p : GS_Edit_Pntr;
  328. begin
  329.    if Total_Lines <= 1 then
  330.    begin
  331.       if not Find_Line(1) then
  332.       begin
  333.          SoundBell(BeepTime,BeepFreq);
  334.          ShowError(750,'Lost track of edit line');
  335.          exit;
  336.       end;
  337.       Work_Line^.Valu_Line := '';
  338.       DelLine;
  339.       exit;
  340.    end;
  341.    Rel_Line_Mem(Active_Line);
  342.    DelLine;
  343.    p := Work_Line;
  344.    CursorLine := succ(Active_Line-Screen_Top);
  345.    if length(Work_Line^.Valu_Line)+1 < CursorPos then
  346.       CursorPos := length(Work_Line^.Valu_Line)+1;
  347.    Show_Lines(Screen_Top,Total_Lines);
  348. end;
  349.  
  350.  
  351. procedure GS_Edit_Objt.Check_Func_Keys;
  352. var
  353.    i : integer;
  354. begin
  355.    case Ch_Work of
  356.             Kbd_F1    : Pressed_F1;
  357.             Kbd_Home  : CursorPos := 1;
  358.             Kbd_End   : CursorPos := Succ(Length(Work_Line^.Valu_Line));
  359.             Kbd_Ins   : begin
  360.                            GS_KeyI_Ins := not GS_KeyI_Ins;
  361.                            GS_Scrn_SetCursor(GS_KeyI_Ins);
  362.                         end;
  363.             Kbd_LfAr  : if CursorPos > 1 then Dec(CursorPos);
  364.             Kbd_RtAr  : if CursorPos <= Length(Work_Line^.Valu_Line) then Inc(CursorPos);
  365.             Kbd_Bsp   : Pressed_Bsp;
  366.             Kbd_Del   : Pressed_Del;
  367.             Kbd_PgUp  : Pressed_PgUp;
  368.             Kbd_PgDn  : Pressed_PgDn;
  369.             Kbd_UpAr  : Pressed_UpAr;
  370.             Kbd_DnAr :  Pressed_DnAr;
  371.             Kbd_Ret   : Pressed_Ret;
  372.             Kbd_Esc   : GS_KeyI_Esc := True;
  373.             #25       : Pressed_CrtlY;  {CTRL-Y}
  374.  
  375.    end;
  376. end;
  377.  
  378. {
  379.          ┌──────────────────────────────────────────────────────────┐
  380.          │  ********        Edit String Procedure         *******   │
  381.          │                                                          │
  382.          │  This is the main method to edit an input string.  The   │
  383.          │  usual cursor keys are processed through a method that   │
  384.          │  may be replaced by a child object's virtual method.     │
  385.          │  The Escape key will terminate and return the default    │
  386.          │  value to the calling program.                           │
  387.          └──────────────────────────────────────────────────────────┘
  388. }
  389.  
  390.  
  391. Procedure GS_Edit_Objt.Edit_Line;
  392. var
  393.    t1 : string;
  394.    lc,
  395.    xl,
  396.    yl,
  397.    i  : integer;
  398. begin
  399.    if Work_Line = nil then
  400.       Work_Line := Get_Line_Mem(Edit_Lgth);
  401.    Insert(Ch_Work, Work_Line^.Valu_Line, CursorPos);
  402.    Inc(CursorPos);                {Step to the next location in the string}
  403.    if not GS_KeyI_Ins then delete(Work_Line^.Valu_Line, CursorPos, 1);
  404.    GoToXY(1, CursorLine);
  405.    Write(Work_Line^.Valu_Line);
  406.    if length(Work_Line^.Valu_Line) >= Edit_Lgth then
  407.       WordWrap(Work_Line^.Valu_Line);
  408. end; { Edit_Line }
  409.  
  410. procedure GS_Edit_Objt.Edit;
  411. var
  412.    stx : string;
  413. begin
  414.    StatWin.SetWin;
  415.    write(' F1 for Help    CTRL-END to Quit    ESC to Abort');
  416.    EditWin.SetWin;
  417.    WW_Flag := false;
  418.    Screen_Top := 0;
  419.    Screen_Btm := 0;
  420.    Ch_Work := #0;
  421.    CursorPos := 1;
  422.    CursorLine := 1;
  423.    Temp_Line := '';
  424.    GS_KeyI_Ins := True;               {Start in insert mode}
  425.    GS_KeyI_Esc := False;              {Set the Escape flag false}
  426.    GS_KeyI_Ret := false;              {Set Return flag false}
  427.    Cursor_LocX := WhereX;
  428.    Cursor_LocY := WhereY;
  429.    Lines_Avail := hi(WindMax) - hi(WindMin);
  430.    inc(Lines_Avail);                  {Adjust for correct number}
  431.    GS_Scrn_SetCursor(GS_KeyI_Ins);    {Go set cursor size}
  432.    if First_Line = nil then
  433.       Work_Line := Get_Line_Mem(Edit_Lgth)
  434.    else
  435.    begin
  436.       Work_Line := First_Line;
  437.       Active_Line := 1;
  438.    end;
  439.    Show_Lines(1,Lines_Avail);
  440.    repeat
  441.       window(1,24,80,24);
  442.       gotoxy(55,1);
  443.       write('Col: ',CursorPos:2,'   Line: ',Active_Line,'':4);
  444.       window(EditWin.X1,EditWin.Y1,EditWin.X2,EditWin.Y2);
  445.       CursorLine := succ(Active_Line-Screen_Top);
  446.       GotoXY(CursorPos, CursorLine);  {Go to current position in the screen}
  447.                                       {write updated part of line}
  448.       Ch_Work := GS_KeyI_GetKey;      {Get the next keyboard entry}
  449.       if (GS_KeyI_Fuc) or (Ch_Work in [#0..#31]) then
  450.                                       {See if function key or control char}
  451.          Check_Func_Keys              {If it is, go process it.}
  452.       else                            {Otherwise add character to the string}
  453.          Edit_Line;                   {Go add character to the line}
  454.    until ((GS_KeyI_Chr = Kbd_CEnd) and
  455.          (GS_KeyI_Fuc)) or (GS_KeyI_Esc);
  456.                                       {Continue until Ctrl-End or Esc pressed}
  457.    GS_Scrn_SetCursor(False);          {Set cursor size to small cursor}
  458.    GS_KeyI_Ins := False;
  459.    EditWin.RelWin;
  460.    StatWin.RelWin;
  461. end;
  462.  
  463.  
  464. procedure GS_Edit_Objt.View;
  465. var
  466.    stx : string;
  467. begin
  468.    StatWin.SetWin;
  469.    write('ESC When Done':45);
  470.    EditWin.SetWin;
  471.    WW_Flag := false;
  472.    Screen_Top := 0;
  473.    Screen_Btm := 0;
  474.    Ch_Work := #0;
  475.    CursorPos := 1;
  476.    CursorLine := 1;
  477.    Temp_Line := '';
  478.    GS_KeyI_Ins := True;               {Start in insert mode}
  479.    GS_KeyI_Esc := False;              {Set the Escape flag false}
  480.    GS_KeyI_Ret := false;              {Set Return flag false}
  481.    Cursor_LocX := WhereX;
  482.    Cursor_LocY := WhereY;
  483.    Lines_Avail := hi(WindMax) - hi(WindMin);
  484.    inc(Lines_Avail);                  {Adjust for correct number}
  485.    if First_Line = nil then
  486.       Work_Line := Get_Line_Mem(Edit_Lgth)
  487.    else
  488.    begin
  489.       Work_Line := First_Line;
  490.       Active_Line := 1;
  491.    end;
  492.    Show_Lines(1,Lines_Avail);
  493.    repeat
  494.       Ch_Work := GS_KeyI_GetKey;      {Get the next keyboard entry}
  495.       if (GS_KeyI_Fuc) or (Ch_Work in [#0..#31]) then
  496.       case Ch_Work of
  497.          Kbd_PgUp : Pressed_PgUp;
  498.          Kbd_PgDn : Pressed_PgDn;
  499.       end;
  500.    until (Ch_Work = Kbd_Esc);
  501.                                       {Continue until Ctrl-End or Esc pressed}
  502.    GS_KeyI_Ins := False;
  503.    EditWin.RelWin;
  504.    StatWin.RelWin;
  505. end;
  506.  
  507. function GS_Edit_Objt.Find_Line(linenum : integer) : boolean;
  508. var
  509.    i : integer;
  510. begin
  511.    if linenum > Total_Lines then
  512.    begin
  513.       Find_Line := false;
  514.       exit;
  515.    end;
  516.    if First_Line = nil then Work_Line := nil
  517.    else
  518.    begin
  519.       Work_Line := First_Line;
  520.       i := 1;
  521.       while (i < linenum) and (Work_Line <> nil) do
  522.       begin
  523.          Work_Line := Work_Line^.Next_Line;
  524.          inc(i);
  525.       end;
  526.    end;
  527.    if Work_Line = nil then
  528.    begin
  529.       Find_line := false;
  530.       ShowError(710,'Find_Line');
  531.    end
  532.    else
  533.    begin
  534.       Find_Line := true;
  535.       Active_Line := linenum;
  536.    end;
  537. end;
  538.  
  539.  
  540. function GS_Edit_Objt.Get_Line_Mem(lth : integer) : pointer;
  541. var
  542.    i : longint;
  543.    p : GS_Edit_Pntr;
  544. begin
  545.    GetMem(Work_Line,lth+15);
  546.    if First_Line = nil then
  547.    begin
  548.       First_Line := Work_Line;
  549.       End_Line := Work_Line;
  550.       Work_Line^.Next_Line := nil;
  551.       Work_Line^.Prev_Line := nil;
  552.       Active_Line := 1;
  553.    end else
  554.    begin
  555.       p := First_Line;
  556.       i := 1;
  557.       while (i < Active_Line) and (p^.Next_Line <> nil) do
  558.       begin
  559.          p := p^.Next_Line;
  560.          inc(i);
  561.       end;
  562.       Work_Line^.Next_Line := p^.Next_Line;
  563.       p^.Next_Line := Work_Line;
  564.       Work_Line^.Prev_Line := p;
  565.       Work_Line^.Next_Line^.Prev_Line := Work_Line;
  566.       inc(Active_Line);
  567.    end;
  568.    Work_Line^.Return_Cod := $0D;
  569.    Work_Line^.Line_Size := lth+15;
  570.    Work_Line^.Valu_Line := '';
  571.    inc(Total_Lines);
  572.    Get_Line_Mem := Work_Line;
  573. end;
  574.  
  575. Procedure GS_Edit_Objt.Rel_Line_Mem(linenum : integer);
  576. var
  577.    wl : GS_Edit_Pntr;
  578. begin
  579.    if First_Line = nil then exit;
  580.    if not Find_Line(linenum) then exit;
  581.    if Work_Line = First_Line then
  582.    begin
  583.       First_Line := Work_Line^.Next_Line;
  584.       if First_Line <> nil then First_Line^.Prev_Line := nil;
  585.    end
  586.    else
  587.    begin
  588.       wl := Work_Line^.Prev_Line;
  589.       Work_Line^.Prev_Line^.Next_Line := Work_Line^.Next_Line;
  590.       if Work_Line^.Next_Line <> nil then
  591.          Work_Line^.Next_Line^.Prev_Line := Work_Line^.Prev_Line;
  592.    end;
  593.    FreeMem(Work_Line,Work_Line^.Line_Size);
  594.    dec(Total_Lines);
  595.    if Total_Lines < Active_Line then Active_Line := Total_Lines;
  596.    if not Find_line(Active_Line) then ShowError(710,'Rel_Line_Mem');
  597. end;
  598.  
  599. Procedure GS_Edit_Objt.Show_Lines(b, e : integer);
  600. var
  601.    i,
  602.    j : integer;
  603.    p : pointer;
  604.    a : longint;
  605. begin;
  606.    if First_Line = nil then exit;
  607.    p := Work_Line;
  608.    a := Active_Line;
  609.    if b > Total_Lines then b := Total_Lines;
  610.    if e > Total_Lines then e := Total_Lines;
  611.    if e >= b + Lines_Avail then e := pred(b+Lines_Avail);
  612.    if not Find_Line(b) then
  613.    begin
  614.       ShowError(710,'Show_Lines');
  615.       Work_Line := p;
  616.       Active_Line := a;
  617.       exit;
  618.    end;
  619.    Screen_Top := b;
  620.    j := 1;
  621.    ClrScr;
  622.    for i := b to e do
  623.    begin
  624.       gotoxy(1,j);
  625.       inc(j);
  626.       write(Work_Line^.Valu_Line);
  627.       ClrEol;
  628.       Work_Line := Work_Line^.Next_Line;
  629.    end;
  630.    Work_Line := p;
  631.    Active_Line := a;
  632. end;
  633.  
  634.  
  635. Procedure GS_Edit_Objt.WordWrap(Fline : string);
  636. var
  637.    lCnt : integer;                    {Counter for line length in characters}
  638.    linterm : byte;                    {Holds line termination code}
  639.    linchr : boolean;
  640.    wrapped : boolean;
  641.    A_L    : longint;
  642.    wLine  : string;
  643.  
  644.  
  645.    function WrapLine : boolean;
  646.    BEGIN                       { WordWrap }
  647.       if (length(wline) <= Edit_Lgth) then
  648.       begin
  649.          WrapLine := false;
  650.          exit;
  651.       end;
  652.       WrapLine := true;
  653.       lCnt := Edit_Lgth+1;
  654.       linchr := false;
  655.       while (not linchr) and (lcnt > 0) do
  656.       begin
  657.          case wline[lCnt] of
  658.             ' '  :  linchr := true;
  659.             '-'  :  linchr := true;
  660.             else    dec(lCnt);
  661.          end;
  662.                                       {Repeat search for space or hyphen until}
  663.                                       {found or current line exhausted}
  664.       end;
  665.       if (lCnt = 0) then lcnt := Edit_Lgth;
  666.                                       {If no break point, truncate line}
  667.       Temp_Line := wline;
  668.       delete(Temp_Line,1,lCnt);
  669.       wline[0] := chr(lcnt);
  670.                                       {Get string up to cursor to split line}
  671.       if (CursorPos < length(wline)) and
  672.          ((Temp_Line = ' ') or (Temp_Line = '')) then
  673.       begin
  674.          WrapLine := false;
  675.          exit;
  676.       end;
  677.    end;
  678.  
  679. BEGIN
  680.    wrapped := false;
  681.    wline := Fline;
  682.    A_L := Active_Line;
  683.    while WrapLine do
  684.    begin
  685.       wrapped := true;
  686.       Work_Line^.Valu_Line := wline;
  687.       linterm := Work_Line^.Return_Cod;
  688.       Work_Line^.Return_Cod := $8D;   {Insert soft return character}
  689.       if linterm = $0D then
  690.       begin
  691.          Work_Line := Get_Line_Mem(Edit_Lgth);
  692.          Work_Line^.Return_Cod := linterm;
  693.       end
  694.       else
  695.       begin
  696.          if not Find_Line(succ(Active_Line)) then
  697.          begin
  698.             Work_Line := Get_Line_Mem(Edit_Lgth);
  699.             Work_Line^.Return_Cod := linterm;
  700.          end;
  701.       end;
  702.       wline := Temp_Line + Work_Line^.Valu_Line;
  703.    end;
  704.    Work_Line^.Valu_Line := wline;
  705.    if not wrapped then exit;
  706.    if not Find_Line(A_L) then
  707.    begin
  708.       ShowError(710,'WordWrap');
  709.    end;
  710.    if (CursorPos > length(Work_Line^.Valu_Line)) and
  711.       (CursorPos <> Edit_Lgth+1) then
  712.    begin
  713.       CursorPos := CursorPos - length(Work_Line^.Valu_Line);
  714.       if not Find_Line(succ(Active_Line)) then
  715.       begin
  716.          ShowError(710,'WordWrap 2');
  717.       end;
  718.    end;
  719.    if ((succ(Active_Line)) - Screen_Top) > Lines_Avail then
  720.    begin
  721.       Screen_Top := (succ(Active_Line)) - Lines_Avail;
  722.    end;
  723.    Show_Lines(Screen_Top, (Screen_Top-1) + Lines_Avail);
  724.    CursorLine := (succ(Active_Line)) - Screen_Top;
  725. end;                         {WordWrap}
  726.  
  727. end.
  728.  
  729. {                           Save for testing                                 }
  730.  
  731. Procedure GS_Edit_Objt.PrintMem;
  732. var
  733.    i,
  734.    j : integer;
  735.    p : pointer;
  736. begin;
  737.    Work_Line := First_Line;
  738.    while Work_Line <> nil do
  739.    begin
  740.       with Work_Line^ do
  741.       begin
  742.          writeln(lst,Return_Cod:4,'   ',Valu_Line);
  743.       end;
  744.       Work_Line := Work_Line^.Next_Line;
  745.    end;
  746. end;
  747.  
  748. end.
  749.